package org.rosa;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.FileWriter;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Objects;
import java.io.InputStreamReader;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;

public class LoginFrame {

    private final JFrame frame;
    private JTextField userText;
    private JPasswordField passwordText;
    private JComboBox<String> userTypeComboBox;
    private static final String USER_FILE = "/users.json";

    public LoginFrame() {
        frame = new JFrame("Grade Tracker Login Frame");
        frame.setSize(600, 400);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocationRelativeTo(null);

        JPanel panel = new JPanel(new GridBagLayout());
        frame.add(panel);
        setContent(panel);
        frame.setVisible(true);
    }

    private void setContent(JPanel panel) {
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.insets = new Insets(10, 10, 10, 10); // 设置组件间距

        JLabel titleLabel = new JLabel("Grade Tracker System", JLabel.CENTER);
        titleLabel.setFont(new Font("Serif", Font.BOLD, 36));

        gbc.gridx = 0;
        gbc.gridy = 0;
        gbc.gridwidth = 3;
        panel.add(titleLabel, gbc);

        JLabel userLabel = new JLabel("Username: ");
        userLabel.setFont(new Font("Serif", Font.PLAIN, 18));
        gbc.gridx = 0;
        gbc.gridy = 1;
        gbc.gridwidth = 1;
        panel.add(userLabel, gbc);

        userText = new JTextField(20);
        gbc.gridx = 1;
        gbc.gridy = 1;
        gbc.gridwidth = 2;
        panel.add(userText, gbc);

        JLabel passwordLabel = new JLabel("Password: ");
        passwordLabel.setFont(new Font("Serif", Font.PLAIN, 18));
        gbc.gridx = 0;
        gbc.gridy = 2;
        panel.add(passwordLabel, gbc);

        passwordText = new JPasswordField(20);
        gbc.gridx = 1;
        gbc.gridy = 2;
        gbc.gridwidth = 2;
        panel.add(passwordText, gbc);

        JLabel userTypeLabel = new JLabel("User Type: ");
        userTypeLabel.setFont(new Font("Serif", Font.PLAIN, 18));
        gbc.gridx = 0;
        gbc.gridy = 3;
        panel.add(userTypeLabel, gbc);

        String[] userTypes = {"Student", "Admin"};
        userTypeComboBox = new JComboBox<>(userTypes);
        gbc.gridx = 1;
        gbc.gridy = 3;
        gbc.gridwidth = 2;
        panel.add(userTypeComboBox, gbc);

        gbc.gridwidth = 1;
        gbc.fill = GridBagConstraints.NONE;

        JButton loginButton = new JButton("Login");
        gbc.gridx = 0;
        gbc.gridy = 4;
        gbc.ipadx = 20;
        panel.add(loginButton, gbc);

        JButton registerButton = new JButton("Register");
        gbc.gridx = 1;
        gbc.gridy = 4;
        panel.add(registerButton, gbc);

        JButton exitButton = new JButton("Exit");
        gbc.gridx = 2;
        gbc.gridy = 4;
        panel.add(exitButton, gbc);

        loginButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                try {
                    String username = userText.getText();
                    String password = String.valueOf(passwordText.getPassword());
                    String userType = (String) userTypeComboBox.getSelectedItem();

                    if (userType != null && verifyLogin(username, password, userType)) {
                        JOptionPane.showMessageDialog(frame, "Login Successful!");
                        frame.dispose();
                        new GradeTracker(userType);
                    } else {
                        JOptionPane.showMessageDialog(frame, "Username, Password or User Type is incorrect!");
                    }
                } catch (Exception ex) {
                    JOptionPane.showMessageDialog(frame, "error occurred: " + ex.getMessage());
                }
            }
        });

        registerButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                try {
                    String username = userText.getText();
                    String password = String.valueOf(passwordText.getPassword());
                    String userType = (String) userTypeComboBox.getSelectedItem();

                    if (userType == null || username.isEmpty() || password.isEmpty()) {
                        JOptionPane.showMessageDialog(frame, "All fields must be filled!");
                        return;
                    }

                    if (!registerUser(username, password, userType)) {
                        JOptionPane.showMessageDialog(frame, "Username already exists!");
                    } else {
                        JOptionPane.showMessageDialog(frame, "Registration Successful!");
                    }
                } catch (Exception ex) {
                    JOptionPane.showMessageDialog(frame, "Error occurred: " + ex.getMessage());
                }
            }
        });

        exitButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                System.exit(0);
            }
        });
    }

    private boolean verifyLogin(String username, String password, String userType) {
        try {
            JSONParser parser = new JSONParser();
            JSONObject data = (JSONObject) parser.parse(new InputStreamReader(Objects.requireNonNull(getClass().getResourceAsStream(USER_FILE))));
            JSONArray users = (JSONArray) data.get("users");

            for (Object obj : users) {
                JSONObject user = (JSONObject) obj;
                if (user.get("username").equals(username) &&
                        user.get("password").equals(password) &&
                        user.get("userType").equals(userType)) {
                    return true;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    private boolean registerUser(String username, String password, String userType) {
        try {
            JSONParser parser = new JSONParser();
            JSONObject data;
            if (Files.exists(Paths.get(Objects.requireNonNull(getClass().getResource(USER_FILE)).toURI()))) {
                data = (JSONObject) parser.parse(new InputStreamReader(Objects.requireNonNull(getClass().getResourceAsStream(USER_FILE))));
            } else {
                data = new JSONObject();
                data.put("users", new JSONArray());
            }

            JSONArray users = (JSONArray) data.get("users");

            for (Object obj : users) {
                JSONObject user = (JSONObject) obj;
                if (user.get("username").equals(username)) {
                    return false;
                }
            }

            JSONObject newUser = new JSONObject();
            newUser.put("username", username);
            newUser.put("password", password);
            newUser.put("userType", userType);

            users.add(newUser);

            try (FileWriter file = new FileWriter(Paths.get(Objects.requireNonNull(getClass().getResource(USER_FILE)).toURI()).toFile())) {
                file.write(data.toJSONString());
            }

            return true;
        } catch (Exception ignored) {
        }
        return false;
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new LoginFrame();
            }
        });
    }
}
